package model

import (
	"encoding/json"
	"fmt"
	"github.com/gogf/gf/v2/util/gconv"
	"time"
)

//客户端请求的消息

const (
	Register = 1000
	Login    = 1001
	Chat     = 1002

	Ping = 2000
)

type IMessage interface {
	Typeis() int32
	Msgis() *Message

	Package() []byte
}

type Message struct { //过度Message，用来在字节流和消息刘中中转
	Type int32
	Msg  interface{}
}

type LoginMessage struct {
	Username string
	Password string
}

type RegisterMessage struct {
	Username string
	Password string
	Email    string
}

type ChatMessage struct {
	Time     time.Time
	FromUser string
	ToUser   string
	Data     string
}

func (chat *ChatMessage) Typeis() int32 {
	return Chat
}

func (chat *ChatMessage) Msgis() *Message {
	return &Message{
		Type: chat.Typeis(),
		Msg:  chat,
	}
}

func (chat *ChatMessage) Package() []byte {
	marshal, err := json.Marshal(chat.Msgis())
	if err != nil {
		panic(err)
	}
	fmt.Println(string(marshal))
	return marshal
}

func (chat *ChatMessage) ToResChat() []byte {
	r := new(ResChatMessage)
	r.MessageFrom = chat.FromUser
	r.MessageTo = chat.ToUser
	r.Data = chat.Data
	r.Time = chat.Time
	fmt.Println("r.Package().......................", r.Package())
	return r.Package()
}

func (register *RegisterMessage) Typeis() int32 {
	return Register
}

func (register *RegisterMessage) Msgis() *Message {
	return &Message{
		Type: register.Typeis(),
		Msg:  register,
	}
}

func (register *RegisterMessage) Package() []byte {
	marshal, err := json.Marshal(register.Msgis())
	if err != nil {
		panic(err)
	}
	fmt.Println(string(marshal))
	return marshal
}

func (login *LoginMessage) Typeis() int32 {
	return Login
}

func (login *LoginMessage) Msgis() *Message {
	return &Message{
		Type: login.Typeis(),
		Msg:  login,
	}
}

func (login *LoginMessage) Package() []byte {
	marshal, err := json.Marshal(login.Msgis())
	if err != nil {
		panic(err)
	}
	fmt.Println(string(marshal))
	return marshal
}

type PingMsg struct {
	Username string
}

func (p *PingMsg) Typeis() int32 {
	return Ping
}

func (p *PingMsg) Msgis() *Message {
	//TODO implement me
	return &Message{
		Type: Ping,
		Msg:  p,
	}
}

func (p *PingMsg) Package() []byte {
	marshal, err := json.Marshal(p.Msgis())
	if err != nil {
		panic(err)
	}
	fmt.Println(string(marshal))
	return marshal
}

func NewRegisterMessage(from *User) *RegisterMessage {
	return &RegisterMessage{
		Username: from.Username,
		Password: from.Password,
		Email:    from.Email,
	}
}

func NewLoginMessage(from *User) *LoginMessage {
	return &LoginMessage{
		Username: from.Username,
		Password: from.Password,
	}
}

func MsgMsgFromAndTo(userFrom User, userTo User, data string) *ChatMessage {
	message := new(ChatMessage)
	message.FromUser = userFrom.Username
	message.ToUser = userTo.Username
	message.Data = data
	return message
}

//返回消息
func UnPackageToMessage(b []byte) IMessage {
	msg := new(Message)
	err := json.Unmarshal(b, msg)
	if err != nil {
		fmt.Println(err)
	}

	switch msg.Type {
	case Register:
		r := new(RegisterMessage)
		gconv.Struct(msg.Msg, r)
		return r
	case Login:
		l := new(LoginMessage)
		gconv.Struct(msg.Msg, l)
		return l
	case Chat:
		c := new(ChatMessage)
		gconv.Struct(msg.Msg, c)
		return c
	}
	return nil
}
